﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using D = System.Drawing;
using Microsoft.Practices.Prism.Regions;
using Infrastucture.Collections;
using TimeSplicerModule.DomainModels;
using TimeSplicerModule.ViewModels;
using TimeSplicerModule.Factories;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using TimeSplicerModule.Controllers;
using TimeSplicerModule.Security;
using TimeSplicerModule.Services;

namespace TimeSplicerModule.Views
{
    /// <summary>
    /// Interaction logic for ProjectListView.xaml
    /// </summary>
    public partial class ProjectListView : UserControl, INavigationAware
    {
        private ProjectListViewModel Model;
        private ISession _session;
        private readonly IUnityContainer _container;
        private readonly IProjectController _projectController;
        private readonly IProjectService _projectService;
        private readonly IProjectFactory _projectFactory;
        private readonly IProjectUserFactory _projectUserFactory;
        private readonly IStatusFactory _statusFactory;
        private readonly IUserFactory _userFactory;
        private readonly IProjectRoleFactory _projectRoleFactory;
        private readonly IPriorityFactory _priorityFactory;
        private readonly ITaskFactory _taskFactory;
        private CancellationTokenSource _cancelToken;

        public ProjectListView(IUnityContainer container, IProjectController projectController, IProjectService projectService, IProjectFactory projectFactory,
            IProjectUserFactory projectUserFactory, IStatusFactory statusFactory, IUserFactory userFactory, IProjectRoleFactory projectRoleFactory, IPriorityFactory priorityFactory,
            ITaskFactory taskFactory)
        {
            InitializeComponent();

            _container = container;
            _projectController = projectController;
            _projectService = projectService;
            _projectFactory = projectFactory;
            _projectUserFactory = projectUserFactory;
            _statusFactory = statusFactory;
            _userFactory = userFactory;
            _projectRoleFactory = projectRoleFactory;
            _priorityFactory = priorityFactory;
            _taskFactory = taskFactory;
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return false; //throw new NotImplementedException();
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            //throw new NotImplementedException();
            _cancelToken.Cancel(false);
            //var handle = _cancelToken.Token.WaitHandle;

         
           
        }

        public async void OnNavigatedTo(NavigationContext navigationContext)
        {
            _session = _container.Resolve<ISession>();

            // todo: need to check paramters to see if tasks should be navigated to

            

            // TODO: Will have to take in parameters whene routing from other pages in the future


            //Model = new ProjectListViewModel();
            //Model.FilteredTasks = new List<TaskModel>();
            //Model.SelectedUserGuid = _session.User.UserGuid;

            //var priorities = _priorityFactory.GetList();
            //Model.Statuses = _statusFactory.GetList(x => x.IsProjectStatus).ToList();
            //Model.Users = _userFactory.GetList();

          
            //Model.Projects = _projectFactory.GetList(Model.Statuses, priorities, Model.Users);
            //// need o change to get projects user is associated with from project users
            //Model.FilteredProjects = Model.Projects.Where(x => x.ProjectManagerGuid == _session.User.UserGuid).ToList();

            // Get Tasks
            //Model.ProjectUsers = _projectUserFactory.GetList();
            //var current = Model.ProjectUsers.Where(x => x.UserGuid == _session.User.UserGuid).ToList();
            //Model.Tasks = _taskFactory.GetList();
            //if (current.Count > 0)
            //{
            //    Model.Tasks.AsParallel().ForAll(x =>
            //        {
            //            if (current.Count(c => c.ProjectUserGuid == x.AssignedToGuid) > 0)
            //                Model.FilteredTasks.Add(x);
            //        });
            //}

            // TODO: Need to default the search to the session user
            // TODO: also need to go and change the style of the 

            //this.itemsGrid.Visibility = System.Windows.Visibility.Hidden;
            this.progressBorder.Visibility = System.Windows.Visibility.Visible;
            this.progressRing.IsActive = true;

            _cancelToken = new CancellationTokenSource();
           
            await Task.Run(() => Model = _projectService.GetProjectListViewModel(), _cancelToken.Token);
            await Task.Yield();
            //Model = _projectService.GetProjectListViewModel();

            // will have to set color statuses here
            //D.Color c = D.Color.FromName(value);
            //Color co = Color.FromArgb(c.A, c.R, c.G, c.B);
            //BrushColor = new SolidColorBrush(co);

            foreach (var p in Model.Projects)
            {
                D.Color c = D.Color.FromName(p.Status.StatusColor);
                Color co = Color.FromArgb(c.A, c.R, c.G, c.B);
                p.Status.BrushColor = new SolidColorBrush(co);

            }

            //this.itemsGrid.Visibility = System.Windows.Visibility.Visible;
            this.progressBorder.Visibility = System.Windows.Visibility.Hidden;
            this.progressRing.IsActive = false; ;


            this.DataContext = Model;
        }

        private void addButton_Click(object sender, RoutedEventArgs e)
        {
            _projectController.NavigateToItemView();
        }

        private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListView grid = sender as ListView;

            if (grid.SelectedItem != null)
            {
                var project = grid.SelectedItem as ProjectModel;
                _projectController.NavigateToItemView(project.ProjectGuid);
            }
        }



        private void searchButton2_Click(object sender, RoutedEventArgs e)
        {
            // TODO:
        }

        private void users1ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            projectSearch();
        }

        private void statusesComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            projectSearch();
        }

        private void search1TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            projectSearch();
        }

        // todo: helpers
        private void projectSearch()
        {
            Model.SearchText = this.search1TextBox.Text;

            // TODO:" I think i need to keep the project users list handy // when user is selected need to check to limit to projects that the user is associated with
            // 

            // so first get projects with id 
            var user = this.users1ComboBox.SelectedItem as UserModel;
            var status = this.statusesComboBox.SelectedItem as StatusModel;
            var projectIds = Model.ProjectUsers.Where(x => x.UserGuid == user.UserGuid).Select(x => x.ProjectGuid).Distinct().ToList();
            List<ProjectModel> projects = new List<ProjectModel>();

            foreach (var p in projectIds)
            {
                var project = Model.Projects.FirstOrDefault(x => x.ProjectGuid == p);

                if (project != null)
                    projects.Add(project);
            }
            

            if (String.IsNullOrEmpty(Model.SearchText))
            {
                if (status == null || status.StatusGuid == Guid.Empty)
                    Model.FilteredProjects = projects.Where(x => x.Status.Status == Infrastucture.Status.Not_Started
                        || x.Status.Status == Infrastucture.Status.Active).ToObservableCollection();
                else
                    Model.FilteredProjects = projects.Where(x => x.StatusGuid == status.StatusGuid).ToObservableCollection();
            }
            else
            {
                if (status == null || status.StatusGuid == Guid.Empty)
                {
                    Model.FilteredProjects = projects.Where(x => x.Name.ToLower().Contains(Model.SearchText.ToLower())
                        && (x.Status.Status == Infrastucture.Status.Active || x.Status.Status == Infrastucture.Status.Not_Started)).ToObservableCollection();
                }
                else
                {
                    Model.FilteredProjects = projects.Where(x => x.StatusGuid == status.StatusGuid
                        && x.Name.ToLower().Contains(Model.SearchText.ToLower())).ToObservableCollection();
                }
            }


            //if (this.statusesComboBox.SelectedItem == null && String.IsNullOrEmpty(Model.SearchText))
            //{
            //    Model.FilteredProjects = Model.Projects.Where(x => x.ProjectManagerGuid == Model.SelectedUserGuid).ToObservableCollection();
            //}
            //else if (this.statusesComboBox.SelectedItem != null && String.IsNullOrEmpty(Model.SearchText))
            //{
            //    Model.FilteredProjects = Model.Projects.Where(x => x.ProjectManagerGuid == Model.SelectedUserGuid
            //        && x.StatusGuid == Model.SelectedStatusGuid).ToObservableCollection();
            //}
            //else if (this.statusesComboBox.SelectedItem == null && !String.IsNullOrEmpty(Model.SearchText))
            //{
            //    Model.FilteredProjects = Model.Projects.Where(x => x.ProjectManagerGuid == Model.SelectedUserGuid
            //        && (x.Name.ToLower().Contains(Model.SearchText.ToLower()) || x.Description.ToLower().Contains(Model.SearchText.ToLower()))).ToObservableCollection();
            //}
            //else if (this.statusesComboBox.SelectedItem != null && !String.IsNullOrEmpty(Model.SearchText))
            //{
            //    Model.FilteredProjects = Model.Projects.Where(x => x.ProjectManagerGuid == Model.SelectedUserGuid
            //        && x.StatusGuid == Model.SelectedStatusGuid
            //        && (x.Name.ToLower().Contains(Model.SearchText.ToLower()) || x.Description.ToLower().Contains(Model.SearchText.ToLower()))).ToObservableCollection();
            //}
        }
    }
}
